<?php
/**
 * 限流
 */
declare(strict_types=1);

namespace Apps\Http\Hooks;

use Exception;
use Libraries\Bases\HookBase;
use Libraries\Config;
use Libraries\Dispatcher;
use Libraries\RateLimit as RT;
use ReflectionObject;

class RateLimit extends HookBase
{
    /**
     * 限流检查
     *
     * @param string $strCtrlAction
     * @param string $strHookType
     * @param array $arrParam
     * @throws Exception
     */
    public function run(
        string $strCtrlAction = '',
        string $strHookType = Dispatcher::HOOK_BEFORE,
        array $arrParam = []
    ): void {
        if ($this->objCtrl->blnOutputEnd || Config::getEnv() === 'dev') {
            return;
        }
        $objRef = new ReflectionObject($this->objCtrl);
        $strCtrlName = $objRef->getName();
        $strRmName = $this->objCtrl->strRemoteIp . '|' . $strCtrlName . '|' . $strCtrlAction;
        if (!RT::check($strRmName, 10, 10, 'rate_limit')) { // 10秒之内，控制器方法最多可访问10次
            $this->objCtrl->objResponse->status(403); // HTTP 403 Forbidden
            $this->objCtrl->blnOutputEnd = true;
        }
        $this->objCtrl->arrHookData['a'] = date('Y-m-d H:i:s');
        unset($objRef, $strCtrlName, $strRmName);
    }
}
